package io.mya.app.user.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonProcessingException;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import io.mya.app.config.LoginRequired;
import io.mya.app.user.service.AppUserService;
import io.mya.app.utils.SHAencrypt;
import io.mya.app.utils.SerialCode;
import io.mya.common.utils.R;
import io.mya.modules.customer.entity.CustomerEntity;
import io.mya.modules.sys.controller.AbstractController;
import io.mya.modules.sys.entity.RegisteredrebateEntity;
import io.mya.modules.sys.oauth2.TokenGenerator;
import io.mya.modules.sys.service.RegisteredrebateService;

/**
 * 用户注册的controller
 * @author shican
 * @date 2018年3月29日
 * 1208296327@qq.com
 */
@RestController
@RequestMapping("/app/user_registered")
public class UserRegisteredController extends AbstractController{
	 private final String BIGKEY = "candy party";

    private final String MAILMARK = "mailmark";


    @Value("${sysUse.rsaKey}")
    private String rsaKey;

    @Value("${candyMail.host}")
    private String host;

    @Value("${candyMail.port}")
    private String port;

    @Value("${candyMail.from}")
    private String from;

    @Value("${candyMail.user}")
    private String user;

    @Value("${candyMail.passwd}")
    private String passwd;
	
	  @Autowired
	  private StringRedisTemplate stringRedisTemplate;
	  @Autowired
	  private AppUserService appUserService;
	  @Autowired
	  private RegisteredrebateService registeredrebateService;
	  
	  
	 /**
     * 发送邮箱，进行注册
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/registerCandy", method = RequestMethod.POST)
    @CrossOrigin
    public R registerCandy(HttpServletRequest request, HttpServletResponse response) {
        String returnMessage = null;
        String invitecode = request.getParameter("code");//邀请码

        Map<String, String> objMap = new HashMap<>();
        try {

            //6位生成随机数
            String randomNumbers = RandomUtil.randomNumbers(6);
            //目前为只发邮箱即可登录 后面需要账号密码
            String registerMail = request.getParameter("regIptEmail");
            //根据邮箱查询是否存在该数据
            CustomerEntity customerEntity = appUserService.queryUserByEmail(registerMail);
            if(customerEntity != null){
            	return R.error("该邮箱已被注册");
            }
            //判断中英 三元表达式
            String language = "";
            if (StrUtil.isEmpty(language)) {
                language = "cn";
            }
            //邮箱返回信息
            String sendInfo = "";

            //放入redis 缓存。。设置验证码有效期
            String existRedis = stringRedisTemplate.opsForValue().get(registerMail);//根据key获取缓存中的val
            //缓存没有 。放入缓存,分钟有效
            if (StrUtil.isEmpty(existRedis)) {
                //向redis里存入数据和设置缓存时间
                stringRedisTemplate.opsForValue().set(registerMail, randomNumbers, 120, TimeUnit.SECONDS);
            } else {

                returnMessage = "false";
                objMap.put("result", returnMessage);
                return R.error("请勿在2分钟内重复注册!");//这里是redis里面有数据 所以请不要多次发送 请勿在一分钟内重复注册
            }
            //发送验证码内容 判断中文、英文
            if (language.equals("en")) {
                sendInfo = (String) stringRedisTemplate.opsForHash().get(BIGKEY, "candyEnHead") + "&"
                        + (String) stringRedisTemplate.opsForHash().get(BIGKEY, "candyEn");
            } else {
                sendInfo = (String) stringRedisTemplate.opsForHash().get(BIGKEY, "candyCnHead") + "&"
                        + (String) stringRedisTemplate.opsForHash().get(BIGKEY, "candyCn");
            }

            if (StrUtil.isEmpty(existRedis)) {
                if (StrUtil.isNotEmpty(registerMail)) {

//                    暂时注释。。节约发邮件
                MailAccount account = new MailAccount();
                account.setHost(this.host); //smtp 服务器地址
                account.setPort(Integer.parseInt(this.port));	//端口
                account.setFrom(this.from); // 发信人
                account.setUser(this.user); //账号
                account.setPass(this.passwd); //密码

                String content = sendInfo.split("&")[0] + randomNumbers + sendInfo.split("&")[1];
                //发送邮件
                MailUtil.send(account, registerMail, sendInfo.split("&")[0], content, true);

                    objMap.put("result", "true");


                } else {
                    returnMessage = "异常情况，请检查邮箱是否正常";
                }

            }

            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
            return R.error(returnMessage);
        }

    }
    /**
     * 发送邮箱，找回密码
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/forgetpass", method = RequestMethod.POST)
    @CrossOrigin
    public R forgetpass(HttpServletRequest request, HttpServletResponse response) {
    	String returnMessage = null;
    	
    	Map<String, String> objMap = new HashMap<>();
    	try {
    		
    		//6位生成随机数
    		String randomNumbers = RandomUtil.randomNumbers(6);
    		//目前为只发邮箱即可登录 后面需要账号密码
    		String registerMail = request.getParameter("regIptEmail");
    		//根据邮箱查询是否存在该数据
    		CustomerEntity customerEntity = appUserService.queryUserByEmail(registerMail);
    		if(customerEntity == null){
    			return R.error("该邮箱还未注册!");
    		}
    		//判断中英 三元表达式
    		String language = "";
    		if (StrUtil.isEmpty(language)) {
    			language = "cn";
    		}
    		//邮箱返回信息
    		String sendInfo = "";
    		
    		//放入redis 缓存。。设置验证码有效期
    		String existRedis = stringRedisTemplate.opsForValue().get(registerMail);//根据key获取缓存中的val
    		//缓存没有 。放入缓存,分钟有效
    		if (StrUtil.isEmpty(existRedis)) {
    			//向redis里存入数据和设置缓存时间
    			stringRedisTemplate.opsForValue().set(registerMail, randomNumbers, 120, TimeUnit.SECONDS);
    		} else {
    			
    			returnMessage = "false";
    			objMap.put("result", returnMessage);
    			return R.error("请勿在2分钟内重复发送!");//这里是redis里面有数据 所以请不要多次发送 请勿在一分钟内重复注册
    		}
    		//发送验证码内容 判断中文、英文
    		if (language.equals("en")) {
    			sendInfo = (String) stringRedisTemplate.opsForHash().get(BIGKEY, "candyEnHead") + "&"
    					+ (String) stringRedisTemplate.opsForHash().get(BIGKEY, "candyEn");
    		} else {
    			sendInfo = (String) stringRedisTemplate.opsForHash().get(BIGKEY, "candyCnHead") + "&"
    					+ (String) stringRedisTemplate.opsForHash().get(BIGKEY, "candyCn");
    		}
    		
    		if (StrUtil.isEmpty(existRedis)) {
    			if (StrUtil.isNotEmpty(registerMail)) {
    				
//                    暂时注释。。节约发邮件
    				MailAccount account = new MailAccount();
    				account.setHost(this.host); //smtp 服务器地址
    				account.setPort(Integer.parseInt(this.port));	//端口
    				account.setFrom(this.from); // 发信人
    				account.setUser(this.user); //账号
    				account.setPass(this.passwd); //密码
    				
    				String content = sendInfo.split("&")[0] + randomNumbers + sendInfo.split("&")[1];
    				//发送邮件
    				MailUtil.send(account, registerMail, sendInfo.split("&")[0], content, true);
    				
    				objMap.put("result", "true");
    				
    				
    			} else {
    				returnMessage = "异常情况，请检查邮箱是否正常";
    			}
    			
    		}
    		
    		return R.ok();
    	} catch (Exception e) {
    		e.printStackTrace();
    		return R.error(returnMessage);
    	}
    	
    }
    /**
     * 找回密码的方法
     * @return
     * @throws Exception 
     * @throws JsonProcessingException
     * verifyCode:验证码
     * password:密码
     * email 邮箱
     */
    @RequestMapping("/forgetpwd")
    @CrossOrigin
    public R forgetpwd(HttpServletRequest request) throws Exception {
    	String invitecode = request.getParameter("verifyCode");//验证码
    	String email = request.getParameter("email");//邮箱
    	String existRedis = stringRedisTemplate.opsForValue().get(email);//判断验证码是否有效
    	if(StrUtil.isEmpty(existRedis)){
    		return R.error("验证码已失效,请重新获取!");
    	}
    	if(!existRedis.equals(invitecode)){
    		return R.error("邮箱验证码错误!");
    	}
    	if(StrUtil.isEmpty(email)){
    		return R.error("邮箱不能为空");
    	}
    	CustomerEntity customerEntity = appUserService.queryUserByEmail(email);
    	if(customerEntity == null){
    		return R.error("该邮箱暂未注册");
    	}
    	
    	String pwd = request.getParameter("pwd");//密码
    	if(StrUtil.isEmpty(pwd)){
    		return R.error("密码不能为空");
    	}
    	//给密码加密
    	String password = SHAencrypt.encryptSHA(pwd);//加密后的密码
    	CustomerEntity entity = new CustomerEntity();
    	entity.setId(customerEntity.getId());
    	entity.setPasswd(password);
    	appUserService.update(entity);
    	return R.ok();
    }
    /**
     * 注册页面注册信息
     * @return
     * @throws Exception 
     * @throws JsonProcessingException
     * accountnumber:注册账号
     * phone:手机号
     * code:验证码
     * verifyCode:邀请码
     * pwd:密码
     * email 邮箱
     */
    @RequestMapping("/registered")
    @CrossOrigin
    public R registered(HttpServletRequest request) throws Exception {
    	String code = request.getParameter("code");//验证码
    	String invitecode = request.getParameter("verifyCode");//邀请码
    	String email = request.getParameter("email");//邮箱
    	String existRedis = stringRedisTemplate.opsForValue().get(email);//判断验证码是否有效
    	if(StrUtil.isEmpty(existRedis)){
    		return R.error("验证码已失效,请重新获取!");
    	}
    	if(!existRedis.equals(code)){
    		return R.error("邮箱验证码错误!");
    	}
    	if(StrUtil.isEmpty(email)){
    		return R.error("邮箱不能为空");
    	}
    	CustomerEntity customerEntity = appUserService.queryUserByEmail(email);
        if(customerEntity != null){
        	return R.error("该邮箱已被注册");
        }
        
    	String pwd = request.getParameter("pwd");//密码
    	if(StrUtil.isEmpty(pwd)){
    		return R.error("密码不能为空");
    	}
    	//给密码加密
    	String password = SHAencrypt.encryptSHA(pwd);//加密后的密码
    	//查找上级id根据邀请码
    	Long parid = appUserService.queryUserByCode(invitecode);
//    	if(StrUtil.isNotEmpty(invitecode)){
//    		//根据邀请码去redis取ID 为防止经常变Redis  如果没有取到 再去数据库查一次
//    		String id = (String) stringRedisTemplate.opsForHash().get("Code",invitecode);
//    		if(StrUtil.isEmpty(id)){
//    			
//    		}else{
//    			parid = Long.parseLong(id);
//    		}
//    	}
    	CustomerEntity entity = new CustomerEntity();
    	entity.setMail(email);
    	entity.setUsername(email);
    	entity.setPasswd(password);
    	entity.setType(1);
    	entity.setStatus(1);
    	entity.setPromoterId(parid);
    	entity.setCreattime(new Date());
    	appUserService.save(entity);
    	return R.ok().put("id", entity.getId());
    }
    /**
     * 注册成功之后根据id来操作页面注册信息
     * @return
     * @throws Exception 
     * @throws JsonProcessingException
     */
    @RequestMapping("/registeredtwo")
    @CrossOrigin
    public R registeredtwo(HttpServletRequest request) throws Exception {
    	String id = request.getParameter("id");//邀请码
    	//根据id查出当前用户
    	CustomerEntity customerEntity = appUserService.queryUserById(Long.parseLong(id));
    	//得到父id
    	Long promoterId = customerEntity.getPromoterId();
    	RegisteredrebateEntity queryObject = registeredrebateService.queryObject();
    	Double rebate = queryObject.getRebate();//给用户自己的返利
    	//根据用户id给用户生成 邀请码
    	String serialCode = SerialCode.toSerialCode(Long.parseLong(id));
    	stringRedisTemplate.opsForHash().put("Code",serialCode,id);
    	CustomerEntity customerEntitynew = new CustomerEntity();
    	customerEntitynew.setId(customerEntity.getId());
    	customerEntity.setInvitecode(serialCode);
    	customerEntity.setCandycount(rebate);
    	appUserService.update(customerEntity);
    	//然后取出对应级别应返利的信息 放入集合中
    	List<Double> list = new ArrayList<>();
    	list.add(queryObject.getRebateone());
    	list.add(queryObject.getRebatetwo());
    	list.add(queryObject.getRebatethree());
    	list.add(queryObject.getRebatefour());
    	list.add(queryObject.getRebatefive());
    	list.add(queryObject.getRebatesix());
    	if(promoterId != null){//说明有上级 那么就层层返利
    		long pid = promoterId;
    		for (int i = 0; i < list.size(); i++) {
    			//根据父类id查询出当前父类 拿到父类信息 主要是为了拿
            	CustomerEntity pcus = appUserService.queryUserById(pid);
            	//因为循环几次就是第几层父类 所以  直接从list里面根据索引取  就是对应的父类的返利
            	Map<String, Object> map = new HashMap<>();
            	map.put("id", pcus.getId());
            	map.put("candycount", list.get(i));
            	appUserService.addCandyCount(map);
            	if(pcus.getPromoterId() == null){
            		break;
            	}
            	pid = pcus.getPromoterId();
    		}
    	}
    	return R.ok();
    }
    /**
     * 登入的方法
     * @return
     * @throws Exception 
     * @throws JsonProcessingException
     */
    @RequestMapping("/login")
    @CrossOrigin
    public R login(HttpServletRequest request) throws Exception {
    	String email = request.getParameter("tEmail");//登入邮箱
    	String password = request.getParameter("tPassWord");//密码
    	//根据邮箱去查询用户  查询到了 说明有 查询不到 就说没有注册
    	CustomerEntity customerEntity = appUserService.queryUserByEmailToLogin(email);
    	if(customerEntity == null){
    		return R.error("该用户不存在或已被禁用!");
    	}
    	String passwd2 = customerEntity.getPasswd();
    	String pwd = SHAencrypt.encryptSHA(password);//加密后的密码
    	if(!passwd2.equals(pwd)){
    		return R.error("用户密码错误,请重新输入!");
    	}
    	//登入成功 更新登入时间
    	CustomerEntity entity = new CustomerEntity();
    	entity.setId(customerEntity.getId());
    	entity.setLogintime(new Date());
    	appUserService.update(entity);
    	//此处就是登入成功了 生成一个token 在redis中存一份 在session中存一份 以此来判断重复登入
    	String token = TokenGenerator.generateValue();
    	customerEntity.setToken(token);
    	//将用户信息存入session中
    	request.getSession().setAttribute("user", customerEntity);
		request.getSession().setMaxInactiveInterval(30 * 60);
		//然后把token存入redis中
		stringRedisTemplate.opsForHash().put("Token",customerEntity.getId().toString(),token);
    	return R.ok().put("token", token);
    }
    /**
     * 登入的方法判断token测试
     * @return
     * @throws Exception 
     * @throws JsonProcessingException
     */
    @RequestMapping("/see")
    @LoginRequired
    @CrossOrigin
    public R see(HttpServletRequest request) throws Exception {
    	//从session中取出用户信息
    	Object attribute = request.getSession().getAttribute("user");
    	CustomerEntity customerEntity = (CustomerEntity) attribute;
    	String token = (String) stringRedisTemplate.opsForHash().get("Token",customerEntity.getId().toString());
    	if(token.equals(customerEntity.getToken())){
    		System.out.println("token正确");
    	}else{
    		System.out.println("不正确");
    	}
    	return R.ok();
    }
    /**
     * 判断是否登入状态来回传参数页面来根据参数显示
     * @return
     * @throws Exception 
     * @throws JsonProcessingException
     */
    @RequestMapping("/islogin")
    @LoginRequired
    @CrossOrigin
    public R islogin(HttpServletRequest request) throws Exception {
    	//从session中取出用户信息
    	Object attribute = request.getSession().getAttribute("user");
    	if(attribute == null){
    		return R.error("退出了或者没有登入!");
    	}else{
    		CustomerEntity customerEntity = (CustomerEntity) attribute;
    		Long id = customerEntity.getId();
    		CustomerEntity customer = appUserService.queryUserById(id);
    		customer.setPasswd(null);
    		return R.ok().put("customer", customer);
    	}
    }
    /**
     * 退出登入
     * @return
     * @throws Exception 
     * @throws JsonProcessingException
     */
    @RequestMapping("/loginout")
    @CrossOrigin
    public R loginout(HttpServletRequest request) throws Exception {
    	request.getSession().removeAttribute("user");
		return R.ok();
    }

    
}
